package com.ysc.ribbon.springcloud.providerconsumer.rule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;

/***
 * 自定义的负载均衡策略
 */
public class GpDefineRule extends AbstractLoadBalancerRule {

    Logger logger = LoggerFactory.getLogger(GpDefineRule.class);

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        return chooseServer(getLoadBalancer(), o);
    }

    private Server chooseServer(ILoadBalancer lb, Object o) {
        logger.info("参数==>{}",o);
        if (lb == null) {
            return null;
        }
        List<Server> uplist = lb.getReachableServers();//所有可用的实例列表
        List<Server> allServers = lb.getAllServers();//所有服务列表
        int cnt = allServers.size();
        if(cnt == 0){
            return null;
        }
        int index = ipAddressHash(cnt);
        return uplist.get(index);
    }

    /**
     * 地址hash得到某个服务实现负载均衡
     * @param cnt
     * @return
     */
    private int ipAddressHash(int cnt) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        String remoteAddr = requestAttributes.getRequest().getRemoteAddr();
        int abs = Math.abs(remoteAddr.hashCode());
        return abs%cnt;
    }
}
